﻿using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace suirui.ZhuMu.Common.Helper
{
    public class MongoHelper
    {
        private static readonly string _connectionString = AppConfigration.Configuration["mongodb"];
        private static readonly string _dbName = AppConfigration.Configuration["mongodbname"];
        private IMongoDatabase mongodb;
        public MongoHelper()
        {
            MongoClient mc = new MongoClient(_connectionString);
            mongodb = mc.GetDatabase(_dbName);
        }

        //单个查询
        public async Task<T> FindAsync<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = await collections.Find(filter).FirstOrDefaultAsync();
            return result;
        }

        public async Task<BsonDocument> FindAsync(string tablename, FilterDefinition<BsonDocument> filter)
        {
            var collections = mongodb.GetCollection<BsonDocument>(tablename);
            var result = await collections.Find(filter).FirstOrDefaultAsync();
            return result;
        }

        public T Find<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var first = collections.Find(filter).FirstOrDefault();
            return first;
        }

        public T Find<T>(string tablename, Expression<Func<T, bool>> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var first = collections.Find(filter).FirstOrDefault();
            return first;
        }

        public T FirstOrDefault<T>(string tablename, string orderbyname, bool isDescending, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            SortDefinition<T> sd = null;
            if (isDescending)
            {
                sd = Builders<T>.Sort.Descending(orderbyname);
            }
            else
            {
                sd = Builders<T>.Sort.Ascending(orderbyname);
            }
            var first = collections.Find(filter).Sort(sd).FirstOrDefault();
            return first;
        }

        //批量查询
        public async Task<List<T>> FindListAsync<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = await collections.Find(filter).ToListAsync();
            return result;
        }

        public List<T> FindList<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var bsonlist = collections.Find(filter).ToList();
            return bsonlist;
        }

        public List<T> FindList<T>(string tablename, FilterDefinition<T> filter, string orderbyname, bool isDescending, int limit)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            SortDefinition<T> sd = null;
            if (isDescending)
            {
                sd = Builders<T>.Sort.Descending(orderbyname);
            }
            else
            {
                sd = Builders<T>.Sort.Ascending(orderbyname);
            }
            var bsonlist = collections.Find(filter).Sort(sd).Limit(limit).ToList();
            return bsonlist;
        }

        public List<T2> Aggregate<T, T2>(string tablename, FilterDefinition<T> filter, BsonDocument bd)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var bsonlist = collections.Aggregate().Match(filter).Group<T2>(bd).ToList();
            return bsonlist;
        }

        public List<T> FindPageList<T>(string tablename, FilterDefinition<T> filter, string orderbyname, bool isDescending, int pageIndex, int pageSize)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            int skip = (pageIndex - 1) * pageSize;
            SortDefinition<T> sd = null;
            if (isDescending)
            {
                sd = Builders<T>.Sort.Descending(orderbyname);
            }
            else
            {
                sd = Builders<T>.Sort.Ascending(orderbyname);
            }
            var list = collections.Find(filter).Sort(sd).Skip(skip).Limit(pageSize).ToList();
            return list;
        }

        public List<T> FindList<T>(string tablename, Expression<Func<T, bool>> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var bsonlist = collections.Find(filter).ToList();
            return bsonlist;
        }

        //插入
        public async Task InsertAsync<T>(string tablename, T t)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            await collections.InsertOneAsync(t);
        }

        public void Insert<T>(string tablename, T t)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            collections.InsertOne(t);
        }

        public async Task InsertManyAsync<T>(string tablename, List<T> t)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            await collections.InsertManyAsync(t);
        }

        public void InsertMany<T>(string tablename, List<T> t)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            collections.InsertMany(t);
        }

        public async Task InsertManyAsync(string tablename, List<BsonDocument> t)
        {
            var collections = mongodb.GetCollection<BsonDocument>(tablename);
            await collections.InsertManyAsync(t);
        }

        public void InsertMany(string tablename, List<BsonDocument> t)
        {
            var collections = mongodb.GetCollection<BsonDocument>(tablename);
            collections.InsertMany(t);
        }

        //批量删除
        public long DeleteMany<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = collections.DeleteMany(filter);
            return result.DeletedCount;
        }

        public async Task<long> DeleteManyAsync<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = await collections.DeleteManyAsync(filter);
            return result.DeletedCount;
        }

        //单个删除
        public bool Delete<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = collections.DeleteOne(filter);
            return result.DeletedCount == 1;
        }

        public bool Delete<T>(string tablename, Expression<Func<T, bool>> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = collections.DeleteOne(filter);
            return result.DeletedCount >= 1;
        }

        public async Task<bool> DeleteAsync<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = await collections.DeleteOneAsync(filter);
            return result.DeletedCount >= 1;
        }

        public async Task<bool> DeleteAsync<T>(string tablename, Expression<Func<T, bool>> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = await collections.DeleteOneAsync(filter);
            return result.DeletedCount >= 1;
        }



        //获取数量
        public long Count<T>(string tablename, FilterDefinition<T> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            return collections.Count(filter);
        }

        public long Count<T>(string tablename, Expression<Func<T, bool>> filter)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            return collections.Count(filter);
        }

        public long Count(string tablename, FilterDefinition<BsonDocument> filter)
        {
            var collections = mongodb.GetCollection<BsonDocument>(tablename);
            return collections.Count(filter);
        }

        //去重查询
        public void Distinct(string tablename, FieldDefinition<BsonDocument, BsonString> field, FilterDefinition<BsonDocument> filter)
        {
            var collections = mongodb.GetCollection<BsonDocument>(tablename);
            collections.Distinct(field, filter);
        }

        //更新数据
        public bool UpdateOne<T>(string tablename, FilterDefinition<T> filter, UpdateDefinition<T> update)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = collections.UpdateOne(filter, update);
            return result.MatchedCount >= 1;
        }

        //批量更新
        public bool UpdateMany<T>(string tablename, FilterDefinition<T> filter, UpdateDefinition<T> update)
        {
            var collections = mongodb.GetCollection<T>(tablename);
            var result = collections.UpdateMany(filter, update);
            return result.MatchedCount >= 1;
        }
    }
}
